package medium

import (
	"fmt"
	"strings"
)

type ListNode struct {
	Val  int
	Next *ListNode
}

func (list *ListNode) String() string {
	str := strings.Builder{}
	if nil != list {
		for ll := list; nil != ll; ll = ll.Next {
			str.WriteString(fmt.Sprintf("%d ", ll.Val))
		}
	}
	return str.String()
}

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	result, carry := 0, false
	var initialNode *ListNode
	var preNode *ListNode
	var currentNode *ListNode
	for ll1, ll2 := l1, l2; nil != ll1 || nil != ll2 || carry; {
		if nil != ll1 {
			result += ll1.Val
		}
		if nil != ll2 {
			result += ll2.Val
		}

		if carry {
			result += 1
		}
		if 10 <= result {
			carry = true
		} else {
			carry = false
		}

		if nil == preNode {
			preNode = &ListNode{Val: result % 10}
			initialNode = preNode
		} else {
			currentNode = &ListNode{Val: result % 10}
			preNode.Next = currentNode

			preNode = currentNode
			currentNode = nil
		}

		if nil != ll1 {
			ll1 = ll1.Next
		} else {
			ll1 = nil
		}
		if nil != ll2 {
			ll2 = ll2.Next
		} else {
			ll2 = nil
		}

		result = 0
	}

	return initialNode
}

func addTwoNumbers1(l1 *ListNode, l2 *ListNode) *ListNode {
	list := ListNode{}

	// a -> ll1
	// b -> ll2
	// result 每位结果值
	// carry 是否进位
	a, b, result, carry, first, preNode, tmpNode := 0, 0, 0, false, true, &list, &ListNode{}
	for ll1, ll2 := l1, l2; nil != ll1 || nil != ll2 || carry; {
		if nil != ll1 {
			a = ll1.Val
		}
		if nil != ll2 {
			b = ll2.Val
		}

		result = a + b
		if carry {
			result += 1
		}

		if 10 <= result {
			carry = true
		} else {
			carry = false
		}

		if first {
			list.Val = result % 10

			first = false
		} else {
			tmpNode.Val = result % 10
			preNode.Next = tmpNode

			preNode = tmpNode
			tmpNode = &ListNode{}
		}

		// 重置a b临时变量
		a = 0
		b = 0

		if nil != ll1 {
			ll1 = ll1.Next
		} else {
			ll1 = nil
		}
		if nil != ll2 {
			ll2 = ll2.Next
		} else {
			ll2 = nil
		}
	}
	return &list
}
